﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ChessSuite.Utilities.Common
{
    public class Position : IEquatable<Position>
    {
        public Position(int file, int rank)
        {
            ValidateCoordinate(file, rank);
            this.File = file;
            this.Rank = rank;
        }

        public int File { get; private set; }
        public int Rank { get; private set; }

        public static bool IsValidFile(int file) { return 0 <= file && file <= 7; }
        public static bool IsValidRank(int rank) { return IsValidFile(rank); }
        public static bool IsValidField(int file, int rank) { return IsValidFile(file) && IsValidRank(rank); }

        public static void ValidateCoordinate(int file, int rank)
        {
            if (!IsValidFile(file))
                throw new ArgumentOutOfRangeException("file", string.Format(Resources.BITBOARD_INDEXER_EXCEPTION_INVALID_FILE_VALUE_FORMAT, file));
            if (!IsValidRank(rank))
                throw new ArgumentOutOfRangeException("rank", string.Format(Resources.BITBOARD_INDEXER_EXCEPTION_INVALID_RANK_VALUE_FORMAT, rank));
        }

        public static char GetFileRepresentation(int file)
        {
            if (!IsValidFile(file))
                throw new ArgumentOutOfRangeException("file", string.Format(Resources.BITBOARD_INDEXER_EXCEPTION_INVALID_FILE_VALUE_FORMAT, file));
            return (char)('1' + file);
        }

        public static char GetRankRepresentation(int rank)
        {
            if (!IsValidRank(rank))
                throw new ArgumentOutOfRangeException("rank", string.Format(Resources.BITBOARD_INDEXER_EXCEPTION_INVALID_RANK_VALUE_FORMAT, rank));
            return (char)('a' + rank);
        }

        public static bool operator ==(Position x, Position y)
        {
            return object.ReferenceEquals(x, null) ?
                object.ReferenceEquals(y, null) : x.Equals(y);
        }
        public static bool operator !=(Position x, Position y)
        {
            return !(x == y);
        }

        public bool Equals(Position other)
        {
            return this.File == other.File && this.Rank == other.Rank;
        }
    }
}
